#include "stdafx.h"
#include "xKernel/IxNode.h"
#include "xKernel/IxView.h"
#include "Util.h"

INT xKernel::GetAlignment(BSTR bsSrc)
{
    INT nAlignment = 0;

    if (!bsSrc)
    {
        ATLASSERT(FALSE);
    }
    else
    {
        CString str(bsSrc);
        INT nPos = str.Find(L"|");
        CString strLeft = str.Left(nPos);
        CString strRight = str.Right(str.GetLength() - nPos - 1);
        if (!strLeft.IsEmpty())
        {
            if (strLeft == L"E_ALIGNMENT_LEFT")
            {
                nAlignment |= E_ALIGNMENT_LEFT;
            }
            else if (strLeft == L"E_ALIGNMENT_RIGHT")
            {
                nAlignment |= E_ALIGNMENT_RIGHT;
            }
            else if (strLeft == L"E_ALIGNMENT_TOP")
            {
                nAlignment |= E_ALIGNMENT_TOP;
            }
            else if (strLeft == L"E_ALIGNMENT_BOTTOM")
            {
                nAlignment |= E_ALIGNMENT_BOTTOM;
            }
            else if (strLeft == L"E_ALIGNMENT_H_CENTER")
            {
                nAlignment |= E_ALIGNMENT_H_CENTER;
            }
            else if (strLeft == L"E_ALIGNMENT_V_CENTER")
            {
                nAlignment |= E_ALIGNMENT_V_CENTER;
            }
            else
            {
                ATLASSERT(!L"wrong alignment !!!");
            }
        }

        if (!strRight.IsEmpty())
        {
            if (strRight == L"E_ALIGNMENT_LEFT")
            {
                nAlignment |= E_ALIGNMENT_LEFT;
            }
            else if (strRight == L"E_ALIGNMENT_RIGHT")
            {
                nAlignment |= E_ALIGNMENT_RIGHT;
            }
            else if (strRight == L"E_ALIGNMENT_TOP")
            {
                nAlignment |= E_ALIGNMENT_TOP;
            }
            else if (strRight == L"E_ALIGNMENT_BOTTOM")
            {
                nAlignment |= E_ALIGNMENT_BOTTOM;
            }
            else if (strRight == L"E_ALIGNMENT_H_CENTER")
            {
                nAlignment |= E_ALIGNMENT_H_CENTER;
            }
            else if (strRight == L"E_ALIGNMENT_V_CENTER")
            {
                nAlignment |= E_ALIGNMENT_V_CENTER;
            }
            else
            {
                ATLASSERT(!L"wrong alignment !!!");
            }
        }
    }

    return nAlignment;
}

bool xKernel::ConvertPointToView(IxView* pView, POINT& pt)
{
    if (!pView)
    {
        return false;
    }

    CRect rcBox(0, 0, 0, 0);
    pView->GetBoxRect(&rcBox);

    pt.x -= rcBox.left;
    pt.y -= rcBox.top;

    return true;
}

void xKernel::GetViewsByPoint(IxView* pView, const CPoint& pt, std::vector< CComPtr<IxView> >& views)
{
    CComQIPtr<IxNode> spNode = pView;
    if (!spNode)
    {
        return;
    }

    INT nCount = 0;
    spNode->GetChildrenCount(&nCount);

    for (INT i = 0; i < nCount; ++i)
    {
        CComPtr<IxNode> spChildNode;
        spNode->GetChildByIndex(i, &spChildNode);
        CComQIPtr<IxView> spView = spChildNode;
        if (!spView)
        {
            continue;
        }

        BOOL bShow = FALSE;
        spView->GetShowState(&bShow);
        if (!bShow)
        {
            continue;
        }

        BOOL bInView = FALSE;
        spView->HitTest(pt, &bInView);

        if (!bInView)
        {
            continue;
        }

        BOOL bEnable;
        spView->GetEnable(&bEnable);

        if (bEnable)
        {
            views.push_back(spView);
            CPoint ptNew = pt;
            ::xKernel::ConvertPointToView(spView, ptNew);
            GetViewsByPoint(spView, ptNew, views);
        }

        break;
    }
}